#include <assert.h>
#include <cstring>
#include <iostream>
#include <list>
using namespace std;

namespace ylz
{
    template <class T>
    struct ListNode
    {
        ListNode<T> *_next;
        ListNode<T> *_prev;
        T _data;
        ListNode(const T &data = T()) : _next(nullptr), _prev(nullptr), _data(data) {}
        //ListNode(T &&data) : _next(nullptr), _prev(nullptr), _data(move(data)) {}//移动构造
        ListNode(T &&data) : _next(nullptr), _prev(nullptr), _data(forward<T>(data)) {}//完美转发策略
    };
    template <class T, class Ref, class Ptr>
    struct ListIterator
    {
        typedef ListNode<T> Node;
        typedef ListIterator<T, Ref, Ptr> Self;
        Node *_node;
        ListIterator(Node *node) : _node(node) {}
        Self &operator++()
        {
            _node = _node->_next;
            return *this;
        }
        Ref operator*() { return _node->_data; }
        bool operator!=(const Self &it) { return _node != it._node; }
    };
    template <class T>
    class list
    {
        typedef ListNode<T> Node;

    public:
        typedef ListIterator<T, T &, T *> iterator;
        typedef ListIterator<T, const T &, const T *> const_iterator;
        iterator begin() { return iterator(_head->_next); }
        iterator end() { return iterator(_head); }
        void empty_init()
        {
            _head = new Node();
            _head->_next = _head;
            _head->_prev = _head;
        }
        list() { empty_init(); }
        void push_back(const T &x) { insert(end(), x); }
        //移动构造
        void push_back(T &&x) { insert(end(), move(x)); }//右值引用的变量是左值
        iterator insert(iterator pos, const T &x)
        {
            Node *cur = pos._node;
            Node *newnode = new Node(x);
            Node *prev = cur->_prev;
            // prev newnode cur
            prev->_next = newnode;
            newnode->_prev = prev;
            newnode->_next = cur;
            cur->_prev = newnode;
            return iterator(newnode);
        }
        iterator insert(iterator pos, T &&x)
        {
            Node *cur = pos._node;
            Node *newnode = new Node(move(x));//右值引用的变量是左值
            Node *prev = cur->_prev;
            // prev newnode cur
            prev->_next = newnode;
            newnode->_prev = prev;
            newnode->_next = cur;
            cur->_prev = newnode;
            return iterator(newnode);
        }

    private:
        Node *_head;
    };
} // namespace bit

namespace ylz
{

    class string
    {
    public:
        typedef char *iterator;
        typedef const char *const_iterator;
        iterator begin() { return _str; }
        iterator end() { return _str + _size; }
        const_iterator begin() const { return _str; }
        const_iterator end() const { return _str + _size; }
        string(const char *str = "") : _size(strlen(str)), _capacity(_size)
        {
            cout << "string(char* str)-构造" << endl;
            _str = new char[_capacity + 1];
            strcpy(_str, str);
        }
        void swap(string &s)
        {
            ::swap(_str, s._str);
            ::swap(_size, s._size);
            ::swap(_capacity, s._capacity);
        }

        string(const string &s) : _str(nullptr)
        {
            cout << "string(const string& s) -- 拷贝构造" << endl;
            reserve(s._capacity);
            for (auto ch : s)
            {
                push_back(ch);
            }
        }

        // 移动构造
        string(string &&s)
        {
            cout << "string(string&& s) -- 移动构造" << endl;
            swap(s);
        }

        string &operator=(const string &s)
        {
            cout << "string& operator=(const string& s) -- 拷贝赋值" << endl;
            if (this != &s)
            {
                _str[0] = '\0';
                _size = 0;
                reserve(s._capacity);
                for (auto ch : s)
                {
                    push_back(ch);
                }
            }
            return *this;
        }
        // 移动赋值
        string &operator=(string &&s)
        {
            cout << "string& operator=(string&& s) -- 移动赋值" << endl;
            swap(s);
            return *this;
        }
        ~string()
        {
            cout << "~string() -- 析构" << endl;
            delete[] _str;
            _str = nullptr;
        }

        char &operator[](size_t pos)
        {
            assert(pos < _size);
            return _str[pos];
        }

        void reserve(size_t n)
        {
            if (n > _capacity)
            {
                char *tmp = new char[n + 1];
                if (_str)
                {
                    strcpy(tmp, _str);
                    delete[] _str;
                }
                _str = tmp;
                _capacity = n;
            }
        }

        void push_back(char ch)
        {
            if (_size >= _capacity)
            {
                size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
                reserve(newcapacity);
            }
            _str[_size] = ch;
            ++_size;
            _str[_size] = '\0';
        }

        string &operator+=(char ch)
        {
            push_back(ch);
            return *this;
        }
        const char *c_str() const { return _str; }

        size_t size() const { return _size; }

    private:
        char *_str = nullptr;
        size_t _size = 0;
        size_t _capacity = 0;
    };
} // namespace ylz

int main()
{
    ylz::list<ylz::string> lt;
    cout << "*************************" << endl;
    ylz::string s1("111111111111111111111");
    lt.push_back(s1);
    cout << "*************************" << endl;
    lt.push_back(ylz::string("22222222222222222222222222222"));
    cout << "*************************" << endl;
    lt.push_back("3333333333333333333333333333");
    cout << "*************************" << endl;
    lt.push_back(move(s1));
    cout << "*************************" << endl;
    return 0;
}